package com.robertux.leaderboard.servlets;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.robertux.leaderboard.beans.JsonResponse;
import com.robertux.leaderboard.beans.RolUsuario;
import com.robertux.leaderboard.beans.entities.Evaluacion;
import com.robertux.leaderboard.beans.entities.Usuario;
import com.robertux.leaderboard.beans.entities.external.Sucursal;
import com.robertux.leaderboard.util.MethodExecutionSecurity;
import com.robertux.leaderboard.util.MethodParamsChecker;
import com.robertux.leaderboard.util.gestoresModelos.GestorEntidadesFarmacia;
import com.robertux.leaderboard.util.gestoresModelos.GestorEvaluaciones;
import com.robertux.leaderboard.util.gestoresModelos.GestorUsuarios;

@WebServlet("/EvaluacionesServlet/*")
public class EvaluacionesServlet extends BaseServlet {
	private static final long serialVersionUID = 1L;
	private Logger logger;
	private GestorEvaluaciones gestorEvs = new GestorEvaluaciones();
	private GestorUsuarios gestorUsr = new GestorUsuarios();
	private DateFormat dateFmt = new SimpleDateFormat("dd/MM/yyyy");
	private NumberFormat numFmt = new DecimalFormat("#.00");
	private GestorEntidadesFarmacia gEntFrm = new GestorEntidadesFarmacia();
       
    /**
     * @see BaseServlet#BaseServlet()
     */
    public EvaluacionesServlet() {
        super();
        this.logger = Logger.getLogger(this.getClass());
    }
    
    @MethodExecutionSecurity(requireAuthentication=true, roleLevelAllowed=RolUsuario.EVALUADOR)
    @MethodParamsChecker(requiredParams={"page", "rowsPerPage", "filter"})
    public JsonResponse getEvaluaciones(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
    	JsonArray arr = new JsonArray();
    	List<Evaluacion> evals;
    	long totalEvaluaciones = 0;
    	if(req.getParameter("branchId") != null) {
    		evals = this.gestorEvs.getEvaluaciones(Integer.parseInt(req.getParameter("branchId")), Integer.parseInt(req.getParameter("page")), Integer.parseInt(req.getParameter("rowsPerPage")), req.getParameter("filter"));
    		totalEvaluaciones = this.gestorEvs.getTotalEvaluaciones(Integer.parseInt(req.getParameter("branchId")), req.getParameter("filter"));
    	} else {
    		evals= this.gestorEvs.getEvaluaciones(Integer.parseInt(req.getParameter("page")), Integer.parseInt(req.getParameter("rowsPerPage")), req.getParameter("filter"));
    		totalEvaluaciones = this.gestorEvs.getTotalEvaluaciones(req.getParameter("filter"));
    	}
    	
    	for(Evaluacion ev: evals) {
    		Sucursal suc = gEntFrm.getSucursal(ev.getUsuario().getSucursalId());
    		JsonObject evObj = new JsonObject();
    		evObj.addProperty("evId", ev.getId());
    		evObj.addProperty("userId", ev.getUsuario().getId());
    		evObj.addProperty("userName", ev.getUsuario().getUsuario() + " - " + ev.getUsuario().getNombre());
    		evObj.addProperty("userEmp", ev.getUsuario().getEmpleadoId());
    		evObj.addProperty("empName", ev.getUsuario().getNombre());
    		evObj.addProperty("fecha", this.dateFmt.format(ev.getFecha()));
    		evObj.addProperty("ponderacion", ev.getPonderacion());
    		evObj.addProperty("nota", this.numFmt.format(ev.getNota()));
    		evObj.addProperty("branch", suc != null? (suc.getId() + " - " + suc.getNombre()): "(ninguna)");
    		arr.add(evObj);
    	}
    	
    	JsonResponse jsonResp = new JsonResponse(0, "OK", "evaluaciones", arr);
    	jsonResp.add("total", new JsonPrimitive(totalEvaluaciones));
    	return jsonResp;
    }
    
    @MethodExecutionSecurity(requireAuthentication=true, roleLevelAllowed=RolUsuario.EVALUADOR)
    @MethodParamsChecker(requiredParams={"userName"})
    public JsonResponse getEvaluacionesUsuario(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
    	Usuario usr = null;
    	JsonArray arr = new JsonArray();
    	if((usr = this.gestorUsr.getUsuario(req.getParameter("userName"))) != null) {
	    	for(Evaluacion ev: usr.getEvaluacions()) {
	    		JsonObject evObj = new JsonObject();
	    		evObj.addProperty("evId", ev.getId());
	    		evObj.addProperty("userId", ev.getUsuario().getId());
	    		evObj.addProperty("userName", ev.getUsuario().getNombre());
	    		evObj.addProperty("userEmp", ev.getUsuario().getEmpleadoId());
	    		evObj.addProperty("empName", ev.getUsuario().getNombre());
	    		evObj.addProperty("fecha", this.dateFmt.format(ev.getFecha()));
	    		evObj.addProperty("ponderacion", ev.getPonderacion());
	    		evObj.addProperty("nota", this.numFmt.format(ev.getNota()));
	    		arr.add(evObj);
	    	}
    	} else {
    		return JsonResponse.fromError(1019, req.getParameter("userName"));
    	}
    	return new JsonResponse(0, "OK", "evaluaciones", arr);
    }
    
    @MethodExecutionSecurity(requireAuthentication=true, roleLevelAllowed=RolUsuario.EVALUADOR)
    @MethodParamsChecker(requiredParams={"userName", "fecha", "ponderacion", "nota"})
    public JsonResponse addEvaluacion(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
    	Usuario usr = null;
    	if((usr = this.gestorUsr.getUsuario(req.getParameter("userName"))) != null) {
    		try {
				Evaluacion ev = new Evaluacion(this.dateFmt.parse(req.getParameter("fecha")), 
						new BigDecimal(this.numFmt.parse(req.getParameter("nota")).doubleValue()), 
						new BigDecimal(req.getParameter("ponderacion")));
				
				usr.addEvaluacion(ev);
				if(this.gestorUsr.actualizarUsuario(usr)) {
					return new JsonResponse(0, "Evaluación agregada satisfactoriamente");
				} else {
					return JsonResponse.fromError(1020);
				}
			} catch (Exception e) {
				this.logger.error("Error tratando de parsear los parámetros de request del servlet: " + e.getMessage(), e);
				return JsonResponse.fromError(1020);
			}
    	} else {
    		return JsonResponse.fromError(1019, req.getParameter("userName"));
    	}
    }
    
    @MethodExecutionSecurity(requireAuthentication=true, roleLevelAllowed=RolUsuario.EVALUADOR)
    @MethodParamsChecker(requiredParams={"evId", "fecha", "ponderacion", "nota"})
    public JsonResponse updateEvaluacion(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
    	Evaluacion ev = null;
    	if((ev = this.gestorEvs.getEvaluacion(Integer.parseInt(req.getParameter("evId")))) != null) {
    		try {
				ev.setFecha(this.dateFmt.parse(req.getParameter("fecha")));
				ev.setNota(new BigDecimal(this.numFmt.parse(req.getParameter("nota")).doubleValue()));
				ev.setPonderacion(new BigDecimal(req.getParameter("ponderacion")));
				if(this.gestorEvs.actualizarEvaluacion(ev)) {
					return new JsonResponse(0, "Evaluación actualizada satisfactoriamente");
				} else {
					return JsonResponse.fromError(1023);
				}
			} catch (Exception e) {
				this.logger.error("Error tratando de actualizar la evaluación: " + e.getMessage(), e);
				return JsonResponse.fromError(1023);
			}
    	} else {
    		return JsonResponse.fromError(1021, req.getParameter("evId"));
    	}
    }
    
    @MethodExecutionSecurity(requireAuthentication=true, roleLevelAllowed=RolUsuario.EVALUADOR)
    @MethodParamsChecker(requiredParams={"evId"})
    public JsonResponse delEvaluacion(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
    	Evaluacion ev = null;
    	if((ev = this.gestorEvs.getEvaluacion(Integer.parseInt(req.getParameter("evId")))) != null) {
    		if(this.gestorEvs.delEvaluacion(ev)) {
    			return new JsonResponse(0, "Evaluación eliminada satisfactoriamente");
    		} else {
    			return JsonResponse.fromError(1022);
    		}
    	} else {
    		return JsonResponse.fromError(1021, req.getParameter("evId"));
    	}
    }

}
